package com.cloud.poetry.file.service.impl;

import cn.hutool.core.util.StrUtil;
import com.cloud.poetry.core.exception.FileException;
import com.cloud.poetry.base.entity.res.SaveFileOutParam;
import com.cloud.poetry.file.service.MiniService;
import com.cloud.poetry.file.service.config.FileProperties;
import io.minio.*;
import io.minio.http.Method;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.InputStream;
import java.time.LocalDate;
import java.util.Objects;

/**
 * @author mengxj
 */
@Slf4j
@Service
public class MiniServiceImpl implements MiniService {

    @Resource
    private FileProperties fileProperties;

    @Resource
    private MinioClient minioClient;

    @Override
    public SaveFileOutParam saveFile(MultipartFile file) {
        if(Objects.isNull(file)){
            throw new FileException("param 'file' can not null");
        }
        String fileName = file.getOriginalFilename();
        int index;
        if(StrUtil.isEmpty(fileName) || (index = fileName.indexOf(".")) == -1){
            throw new FileException(String.format("file's name is illegal: %s", fileName));
        }
        String suffix = fileName.substring(index + 1);
        String bucket = this.fileProperties.getBucket();
        try {
            log.info("check and create bucket");
            BucketExistsArgs bucketExistsArgs = BucketExistsArgs.builder().bucket(bucket).build();
            boolean isExist = this.minioClient.bucketExists(bucketExistsArgs);
            if(!isExist){
                log.info("bucket {} is not exists, make is start!", bucket);
                MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket(bucket).build();
                this.minioClient.makeBucket(makeBucketArgs);
            }
            InputStream is = file.getInputStream();
            String objectName = String.format("%s/%s/%s/%s", LocalDate.now().toString(), suffix, System.currentTimeMillis(), fileName);
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .contentType("application/octet-stream").bucket(bucket)
                    .object(objectName)
                    .stream(is, is.available(), -1).build();
            this.minioClient.putObject(putObjectArgs);
            GetPresignedObjectUrlArgs urlArgs = GetPresignedObjectUrlArgs.builder().object(objectName).bucket(bucket).method(Method.GET).build();
            String url = this.minioClient.getPresignedObjectUrl(urlArgs);
            log.info("save file finish, url is {}", url);
            return SaveFileOutParam.builder().bucket(bucket).objectName(objectName).url(url).build();
        } catch (Exception e) {
            e.printStackTrace();
            throw new FileException(String.format("saveFile error! %s: %s", e.getClass(), e.getMessage()));
        }
    }

    @Override
    public void removeFile(String bucket, String objectName) {
        try {
            RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(bucket).object(objectName).build();
            this.minioClient.removeObject(removeObjectArgs);
        }catch (Exception e){
            e.printStackTrace();
            throw new FileException(String.format("delete file error! param bucket %s objectName %s, msg ==> %s: %s", bucket, objectName, e.getClass(), e.getMessage()));
        }
    }
}
